/**
 *  @file SDLButton.h
 *
 *  @date 23-nov-2009
 *  @author Ives van der Flaas
 */

#ifndef SDLBUTTON_H_
#define SDLBUTTON_H_

#include <string>
#include <SDL.h>
#include "vector2.h"
#include "SDLApplicationSection.h"
#include "SDLStaticRepresentation.h"
#include "SDLTextRepresentation.h"
#include "SDLRectangleRepresentation.h"
#include "multistateRepresentation.h"
#include "buttonID.h"


namespace si_sdl
{
/**
 * A button in an SDL Program. This will use callback to let you know when it was clicked.
 * It changes rep on mouse over. It does unfortunately for the moment have a fixed size
 * so limit the amount of text in your button!
 */
class SDLButton
{
public:
	/**
	 * Ctor
	 * @param thisButtonsID returns handle to this button
	 * @param position Position of this button (lower left corner)
	 * @param size Size
	 * @param buttonText Text on the button
	 * @param parent ApplicationSection which owns this button
	 * @param onClick the function that will be called when the button is clicked
	 * @return
	 */
	SDLButton(
			ButtonID& thisButtonsID,
			si::Vector2 position,
			si::Vector2 size,
			std::string buttonText,
			SDLApplicationSection& parent,
			void (SDLApplicationSection::*onClick)(ButtonID));

	/**
	 * Copy ctor
	 * @param b The button te be copied
	 * @return
	 */
	SDLButton(const SDLButton& b);

	void draw();
	void update(double time);
	void positionButton(std::string xPos, std::string yPos);

	virtual ~SDLButton();

	/**
	 * Processes all relevant SDL events.
	 * This needs to be called for every new SDL_Event
	 * @param event
	 */
	virtual void onSDLEvent(SDL_Event& event);

	/**
	 * Sets focus to this button. This means it's color will change and it'll react to
	 * ENTER and SPACE bar by pretending it was clicked.
	 */
	void setFocus();

	/**
	 * Loses focus for this button. Undoes all effects of setFocus();
	 */
	void loseFocus();

	/**
	 * Sets the button's horizontal position
	 * @param newXPos New upperleft x position
	 */
	void setHorizontalPosition(double newXPos){ fPosition.setX(newXPos); }

	void setVerticalPosition(double newYPos) { fPosition.setY(newYPos); }

	/**
	 * Hides the button
	 */
	void hide() { fVisible = false; }

	/**
	 * Shows the button
	 */
	void show() { fVisible = true; }


private:

	/**
	 * Will execute when button is clicked and
	 * call the callback.
	 */
	void executeClick();

	/**
	 * Is executed on mouse over.
	 */
	void mouseOver();

	/**
	 * Is executed on mouse out.
	 */
	void mouseOut();

	ButtonID fButtonID;
	si::Vector2 fPosition;
	si::Vector2 fSize;
	std::string fText;
	bool fMouseHovering;
	bool fHasFocus;
	SDLApplicationSection &fParentSection;

	void (SDLApplicationSection::*fOnClick)(ButtonID);

	static int fNrOfButtons;

	si::MultistateRepresentation fBox;

	si::StateID fFocussed;
	si::StateID fNonFocussed;

	bool fVisible;
};

}

#endif /* SDLBUTTON_H_ */
